55. 跳跃游戏
55. 跳跃游戏
Similar Question
Solution Tips
方案一: 暴力法 + 模拟
var canJump = function(nums) {
if (nums.length === 1) {
return true;
}
// 反过来看会不会更好呢? 看倒数第二个, 能不能去到 last
// 再找到能去倒数第二的, 如果不能就从倒数第三看能不能去 last
// 感觉又是回溯, 自从做完回溯了, 看啥都是回溯
for (let i = nums.length - 2; i >= 0 ; i--) {
let last = nums.length - 1;
let j = i;
while (j >= 0) {
// 先找到一个能跳到last的,如果最终行不通就 next 呗
if (nums[j] >= (last - j)) {
last = j;
j--;
}
else {
j--;
}
}
if (last === 0) {
return true;
}
}
return false;
};
方案二: 贪心
刚看到本题一开始可能想:当前位置元素如果是 3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢?
其实跳几步无所谓,关键在于可跳的覆盖范围!
不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
这个范围内,别管是怎么跳的,反正一定可以跳过来。
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
局部最优推出全局最优,找不出反例,试试贪心!
这种方法所依据的核心特性:如果一个位置能够到达,那么这个位置左侧所有位置都能到达。 想到这一点,解法就呼之欲出了~
var canJump = function(nums) {
if(nums.length === 1) return true
let cover = 0
for(let i = 0; i <= cover; i++) {
cover = Math.max(cover, i + nums[i])
if(cover >= nums.length - 1) {
return true
}
}
return false
};